package com.kavin.network;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LifecycleOwner;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

/**
 * 兼容所有版本api
 * author: kavin_tian
 * 自动管理网络广播的生命周期
 */
public class NetworkUtils {


    /**
     * 兼容所有版本api
     * author: kavin_tian
     */
    public static final int NO_NETWORK = -1;
    public static final int CMNET = 1;
    public static final int CMWAP = 2;
    public static final int WIFI = 3;


    public static int getConnectionType(Context context) {
        int netType = NO_NETWORK;
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo curNetwork = connectivity.getActiveNetworkInfo();
            if (curNetwork != null) {
                int nType = curNetwork.getType();
                if (nType == ConnectivityManager.TYPE_MOBILE) {
                    String extraInfo = curNetwork.getExtraInfo();
                    if (extraInfo != null) {
                        String sType = curNetwork.getExtraInfo().toLowerCase();
                        if (sType.equals("cmnet")) {
                            netType = CMNET;
                        } else {
                            netType = CMWAP;
                        }
                    }
                } else if (nType == ConnectivityManager.TYPE_WIFI) {
                    netType = WIFI;
                }
            }
        }

        return netType;
    }
    /*
        手机网络进行详细区分：
        info.getSubtype() 这里使用 getSubtype()，不是 getType()，getType()返回的是0，或者1，是区分是手机网络还是wifi

        info.getSubtype()取值列表如下：
            TelephonyManager.NETWORK_TYPE_CDMA 网络类型为CDMA
            NETWORK_TYPE_EDGE 网络类型为EDGE
            NETWORK_TYPE_EVDO_0 网络类型为EVDO0
            NETWORK_TYPE_EVDO_A 网络类型为EVDOA
            NETWORK_TYPE_GPRS 网络类型为GPRS
            NETWORK_TYPE_HSDPA 网络类型为HSDPA
            NETWORK_TYPE_HSPA 网络类型为HSPA
            NETWORK_TYPE_HSUPA 网络类型为HSUPA
            NETWORK_TYPE_UMTS 网络类型为UMTS

        联通的3G为UMTS或HSDPA，移动和联通的2G为GPRS或EDGE，电信的2G为CDMA，电信的3G为EVDO
    */

    public static boolean isNetworkFor2G(Context context) {
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity == null) {
            return false;
        } else {
            NetworkInfo curNetwork = connectivity.getActiveNetworkInfo();
            if (curNetwork != null && curNetwork.getType() == 0) {
                int nType = curNetwork.getSubtype();

                if (nType == TelephonyManager.NETWORK_TYPE_GPRS || nType == TelephonyManager.NETWORK_TYPE_EDGE || nType == TelephonyManager.NETWORK_TYPE_CDMA) {
                    return true;
                }
            }

            return false;
        }
    }

    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity == null) {
            return false;
        } else {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) {
                for (int i = 0; i < info.length; ++i) {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }

            return false;
        }
    }

    public static String getTypeName(Context context) {
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo curNetwork = connectivity.getActiveNetworkInfo();
            if (curNetwork != null) {
                int nType = curNetwork.getType();
                if (nType == ConnectivityManager.TYPE_WIFI) {
                    return curNetwork.getTypeName();
                }

                if (nType == ConnectivityManager.TYPE_MOBILE) {
                    return curNetwork.getSubtypeName();
                }

                return "UNKNOWN";
            }
        }

        return "UNKNOWN";
    }

    public static String getWifiMacAddress(Context context) {
        WifiManager mWifi = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
        if (mWifi != null && mWifi.isWifiEnabled()) {
            return MacUtils.getMacAddress(context);
        } else {
            return null;
        }
    }

    public static boolean isWifi(Context mContext) {
        ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI;
    }

    /**
     * 获取手机的ip地址
     */
    public static String getPhoneIp() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        //if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet6Address) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (Exception e) {
        }
        return "";
    }

    /*==============================================================下面是网络变化监听==============================================================*/

    /**
     * 网络变化回调接口
     */
    public interface OnChangeListener {
        void onChange(NetworkInfo networkInfo, boolean isConnected);
    }

    public static void setOnChangeListener(@NonNull AppCompatActivity activity, OnChangeListener onChangeListener) {
        new NetworkStatus().setOnChangeListener(activity, onChangeListener);
    }


    public static class NetworkStatus {
        public OnChangeListener onChangeListener;
        private AppCompatActivity activity;
        private NetWorkStateReceiver netWorkStateReceiver;

        public void setOnChangeListener(@NonNull AppCompatActivity activity, OnChangeListener onChangeListener) {
            this.activity = activity;
            this.onChangeListener = onChangeListener;
            addLifecycle(activity);
            registerReceiverNetwork();
        }


        private void registerReceiverNetwork() {
            if (netWorkStateReceiver == null) {
                netWorkStateReceiver = new NetWorkStateReceiver(onChangeListener);
            }

            IntentFilter filter = new IntentFilter();
            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
            activity.registerReceiver(netWorkStateReceiver, filter);
            Log.d("------NetworkUtils", "注册 网络变化广播 from " + activity.getLocalClassName());
        }

        private void unregisterReceiverNetwork() {
            activity.unregisterReceiver(netWorkStateReceiver);
            Log.d("------NetworkUtils", "注销 网络变化广播 from " + activity.getLocalClassName());
        }


        /**
         * 添加生命周期观察 ,界面销毁后注销广播,
         */
        private void addLifecycle(@NonNull LifecycleOwner lifecycleOwner) {
            lifecycleOwner.getLifecycle().addObserver(new MyLifecycleEventObserver() {
                @Override
                public void onDestroy() {
                    unregisterReceiverNetwork();
                }
            });
        }

    }


}
